#include "user_device.h"
#include "user_global.h"
#include "tim.h"

///////////////////////////////////////////////////////////////
// beep
ulong beep_tick = 0;
uchar beeping = 0;
uchar beep_mode = 0;

#if BEEP_MULTI_FREQ

#define MAX_BEEP_TONE_COUNT  10

// 蜂鸣器全局参数
typedef struct BEEP_TABLE
{
    ushort freq_table[MAX_BEEP_TONE_COUNT];         // 频率,<1代表无声
    ushort tone_interval[MAX_BEEP_TONE_COUNT];      // 间隔时间ms
    uchar tone_count;                               // 频响次数
} BEEP_TABLE;

/*
{
       low mid high
    DO 262 523 1046
    RE 294 587 1175
    MI 330 659 1318
    FA 349 698 1397
    SO 392 784 1568
    LA 440 880 1760
    SI 494 988 1967
}
*/
//1ms
BEEP_TABLE beep_table[] =
{
    {{2730},{50}, 1},
    {{2730},{100},1},
    {{800}, {400},1},
    {{1500},{600},1},
    {{2000},{700},1},

    {{1209},{30},1},
    {{650,731,812},{50,50,50},3},
    {{812,731,650},{500,500,500},3},
    {{866,975,1083},{500,500,500},3},
    {{2437,2600,2900},{500,500,500},3},
    {{262,392},{500,500},2},
    {{349},{500},1},
    {{1733},10,1},
    {{866},500,1}
};
#endif

//蜂鸣器控制
typedef struct BEEP_CNTRL
{
    uchar mode;             // 声响模式
    uchar index;            // 当前模式下的频率索引
    ushort freq;            // 频率, Hz
    ulong tick;             // 时长, system tick
} BEEP_CNTRL;

BEEP_CNTRL beep_cntrl;

void B_Set_Timer(ushort tick)
{
#define MIN_TIM12_TICK       2

    if(tick < MIN_TIM12_TICK)
        tick = MIN_TIM12_TICK;
    timer_autoreload_value_config(TIMER12, tick);
    timer_channel_output_pulse_value_config(TIMER12, TIMER_CH_0, tick >> 1 );
}

void B_Start_Timer()
{
    timer_enable(TIMER12);
}

void B_Stop_Timer()
{
    timer_disable(TIMER12);
}

// 设置查询间隔
void B_Set_Interval(ushort interval)
{
    beep_cntrl.tick = US_TO_TICK(interval*1000);
}

void Stop_Beep(void)
{
    beeping = 0;
    B_Stop_Timer();
}

void Reset_Beep(void)
{
    Stop_Beep();
}

#if BEEP_MULTI_FREQ
void Start_Beep(uchar mode)
{
#if (ENABLE_BEEP)
    ushort tick;
    Reset_Beep();
    beep_cntrl.mode = mode;
    beep_cntrl.index = 0;
    tick = beep_table[beep_cntrl.mode].freq_table[beep_cntrl.index];
    beep_tick = SystemTick();
    if(tick > 1)
    {
        B_Set_Timer(TIMER12_CLK/tick);
        B_Start_Timer();
        B_Set_Interval(beep_table[beep_cntrl.mode].tone_interval[beep_cntrl.index]);
        beeping = 1;
    }
    else
    {
        B_Stop_Timer();
    }
#endif
}

void Beep_Loop(void)
{
#if (ENABLE_BEEP)
    if(beeping)
    {
        ++beep_cntrl.index;
        if(beep_cntrl.index >= beep_table[beep_cntrl.mode].tone_count)
        {
            Reset_Beep();
        }
        else
        {
            beep_tick = SystemTick();
            if(beep_table[beep_cntrl.mode].freq_table[beep_cntrl.index] > 1)
            {
                B_Set_Timer(TIMER12_CLK / beep_table[beep_cntrl.mode].freq_table[beep_cntrl.index]);
                B_Start_Timer();
            }
            else
            {
                B_Stop_Timer();
            }
            B_Set_Interval(beep_table[beep_cntrl.mode].tone_interval[beep_cntrl.index]);

        }
    }
#endif
}

void Beep_Cntrol()
{
#if (ENABLE_BEEP)
    if(SystemTick() - beep_tick > beep_cntrl.tick)
        Beep_Loop();
#endif
}

#else

void Start_Beep(uchar mode)
{
#if (ENABLE_BEEP)
    if (mode < BEEP_USER)
    {
        beep_cntrl.freq = ((ushort *)&rw_word.beep_freq_for_info)[mode << 1];
        beep_cntrl.tick = ((ushort *)&rw_word.beep_freq_for_info)[(mode << 1) + 1];
    }
    else
    {
        beep_cntrl.freq = rw_word.action_args[0];
        beep_cntrl.tick = rw_word.action_args[1];
    }

    // ms -> tick
    beep_cntrl.tick = US_TO_TICK(beep_cntrl.tick * 1000);

    Stop_Beep();
    beep_tick = SystemTick();
    beep_cntrl.mode = mode;

    if(beep_cntrl.freq)
    {
        B_Set_Timer(TIMER12_CLK / beep_cntrl.freq);
        B_Start_Timer();

        beeping = 1;
    }
    else
    {
        B_Stop_Timer();
    }
#endif
}

void Beep_Cntrol()
{
#if (ENABLE_BEEP)
    if(SystemTick() - beep_tick > beep_cntrl.tick)
        Stop_Beep();
#endif
}
#endif
